package com.ikas.ai.server.module.alarm.service;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.ikas.ai.consts.MachineAndWorkConditionConst;
import com.ikas.ai.enums.redis.RedisKeyEnum;
import com.ikas.ai.server.module.alarm.dao.TripAlarmDAO;
import com.ikas.ai.server.module.alarm.dao.UnitDeteriorationAlarmDAO;
import com.ikas.ai.server.module.alarm.enums.SolvedEnum;
import com.ikas.ai.server.module.alarm.model.TripAlarm;
import com.ikas.ai.server.module.alarm.model.UnitDeteriorationAlarm;
import com.ikas.ai.server.module.alarm.model.dto.AlarmStateDTO;
import com.ikas.ai.server.module.alarm.model.enums.AlarmType;
import com.ikas.ai.server.module.steady.dao.SteadyAlarmDataMapper;
import com.ikas.ai.server.module.steady.model.dto.SteadyAlarmCacheDTO;
import com.ikas.ai.utils.ObjectUtil;
import com.ikas.ai.utils.RedisUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AlarmCacheService {

    private final String ALARM_STATE_KEY = RedisKeyEnum.ALARM_STATE_KEY.key();

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    private TripAlarmDAO tripAlarmDAO;
    @Autowired
    private UnitDeteriorationAlarmDAO unitDeteriorationAlarmDAO;
    @Autowired
    private SteadyAlarmDataMapper steadyAlarmDataMapper;

    public AlarmStateDTO round() {
        AlarmStateDTO bean = new AlarmStateDTO();
        //更新跳机
        LambdaQueryChainWrapper<TripAlarm> tripAlarmLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(tripAlarmDAO);
        List<TripAlarm> tripAlarmList = tripAlarmLambdaQueryChainWrapper.eq(TripAlarm::getSolved, TripAlarm.ALARM_NOT_SOLVED).list();
        if (CollectionUtils.isNotEmpty(tripAlarmList)) {
            Map<String, List<TripAlarm>> tripMap = tripAlarmList.stream().filter(i -> StringUtils.isNotBlank(i.getMachineNo())).collect(Collectors.groupingBy(TripAlarm::getMachineNo));
            tripMap.forEach((k, v) -> this.makeAlarm(AlarmType.TRIP, k, v.size(), bean));
        }
        //更新机组
        LambdaQueryChainWrapper<UnitDeteriorationAlarm> unitLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(unitDeteriorationAlarmDAO);
        List<UnitDeteriorationAlarm> unitDeteriorationAlarmList = unitLambdaQueryChainWrapper.eq(UnitDeteriorationAlarm::getSolved, TripAlarm.ALARM_NOT_SOLVED).list();
        if (CollectionUtils.isNotEmpty(unitDeteriorationAlarmList)) {
            Map<String, List<UnitDeteriorationAlarm>> unitMap = unitDeteriorationAlarmList.stream().filter(i -> StringUtils.isNotBlank(i.getMachineNo())).collect(Collectors.groupingBy(UnitDeteriorationAlarm::getMachineNo));
            unitMap.forEach((k, v) -> this.makeAlarm(AlarmType.UNIT_DETERIORATION, k, v.size(), bean));
        }
        //更新稳态预警
        List<SteadyAlarmCacheDTO> list = steadyAlarmDataMapper.selectCountBySolved(SolvedEnum.UN_SOLVED.getSolved());
        if (CollectionUtils.isNotEmpty(list)) {
            Map<String, List<SteadyAlarmCacheDTO>> map = list.stream().filter(i -> StringUtils.isNotBlank(i.getMachineNo())).collect(Collectors.groupingBy(SteadyAlarmCacheDTO::getMachineNo));
            map.forEach((k, v) -> this.makeAlarm(AlarmType.STEADY_ALARM, k, v.size(), bean));
        }
        return bean;
    }

    public AlarmStateDTO updateAlarmState() {
        AlarmStateDTO bean;
        //更新跳机
        LambdaQueryChainWrapper<TripAlarm> tripAlarmLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(tripAlarmDAO);
        List<TripAlarm> tripAlarmList = tripAlarmLambdaQueryChainWrapper.eq(TripAlarm::getSolved, TripAlarm.ALARM_NOT_SOLVED).list();
        Map<String, List<TripAlarm>> tripMap = tripAlarmList.stream().filter(i -> StringUtils.isNotBlank(i.getMachineNo())).collect(Collectors.groupingBy(TripAlarm::getMachineNo));
        tripMap.forEach((k, v) -> this.updateAlarm(AlarmType.TRIP, k, v.size()));
        //更新机组
        LambdaQueryChainWrapper<UnitDeteriorationAlarm> unitLambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(unitDeteriorationAlarmDAO);
        List<UnitDeteriorationAlarm> unitDeteriorationAlarmList = unitLambdaQueryChainWrapper.eq(UnitDeteriorationAlarm::getSolved, TripAlarm.ALARM_NOT_SOLVED).list();
        Map<String, List<UnitDeteriorationAlarm>> unitMap = unitDeteriorationAlarmList.stream().filter(i -> StringUtils.isNotBlank(i.getMachineNo())).collect(Collectors.groupingBy(UnitDeteriorationAlarm::getMachineNo));
        unitMap.forEach((k, v) -> this.updateAlarm(AlarmType.UNIT_DETERIORATION, k, v.size()));
        //更新稳态预警
        List<SteadyAlarmCacheDTO> list = steadyAlarmDataMapper.selectCountBySolved(SolvedEnum.UN_SOLVED.getSolved());
        Map<String, List<SteadyAlarmCacheDTO>> map = list.stream().filter(i -> StringUtils.isNotBlank(i.getMachineNo())).collect(Collectors.groupingBy(SteadyAlarmCacheDTO::getMachineNo));
        map.forEach((k, v) -> this.updateAlarm(AlarmType.STEADY_ALARM, k, v.size()));
        bean = redisUtil.getBean(ALARM_STATE_KEY, AlarmStateDTO.class);
        return bean;
    }

    public void updateAlarm(AlarmType type, String machineNo, Integer num) {
        AlarmStateDTO cacheBean = redisUtil.getBean(ALARM_STATE_KEY, AlarmStateDTO.class);
        if (ObjectUtil.isNull(cacheBean)) {
            cacheBean = new AlarmStateDTO();
        }
        switch (machineNo) {
            case MachineAndWorkConditionConst.MACHINE_01_NO:
                cacheBean.getU01State().setAlarm(type, num);
                break;
            case MachineAndWorkConditionConst.MACHINE_02_NO:
                cacheBean.getU02State().setAlarm(type, num);
                break;
            case MachineAndWorkConditionConst.MACHINE_03_NO:
                cacheBean.getU03State().setAlarm(type, num);
                break;
            case MachineAndWorkConditionConst.MACHINE_04_NO:
                cacheBean.getU04State().setAlarm(type, num);
                break;
        }
        //设置一天有效时间
        redisUtil.saveBean(ALARM_STATE_KEY, cacheBean, 86400);
    }

    public void makeAlarm(AlarmType type, String machineNo, Integer num, AlarmStateDTO cacheBean) {
        switch (machineNo) {
            case MachineAndWorkConditionConst.MACHINE_01_NO:
                cacheBean.getU01State().setAlarm(type, num);
                break;
            case MachineAndWorkConditionConst.MACHINE_02_NO:
                cacheBean.getU02State().setAlarm(type, num);
                break;
            case MachineAndWorkConditionConst.MACHINE_03_NO:
                cacheBean.getU03State().setAlarm(type, num);
                break;
            case MachineAndWorkConditionConst.MACHINE_04_NO:
                cacheBean.getU04State().setAlarm(type, num);
                break;
        }
    }
}
